﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace MINERP.BLL.Common
{
    /// <summary>
    /// 文件和文件夹的复制、剪切、删除等操作
    /// </summary>
    public class FileBLL
    {
        [DllImport("kernel32.dll")]
        public static extern int WinExec(string exeName, int operType);
        //  int ret = WinExec(@"explorer /n,/select," + fileName, 1);
        //打开此文件并选中

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        //(int)FindWindow(null, formName);
        //找到窗体名称为formName的窗体，如果找到了返回值>0

        //[DllImport("shell32.dll ")]
        //public static extern int ShellExecute(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int FsShowCmd);

        [DllImport("shell32.dll")]
        public static extern int ShellExecute(int hwnd, string lpszOp, string lpszFile, string lpszParams, string lpszDir, int FsShowCmd);
        //指行指令，如下面这条就是打开一个文件夹
        // ShellExecute(IntPtr.Zero, new StringBuilder("open"), new StringBuilder("explorer.exe"), new StringBuilder(fullName), new StringBuilder(string.Empty), 1);

        /// <summary>
        /// 打开文件夹
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="lpszOp"></param>
        /// <param name="lpszFile"></param>
        /// <param name="lpszParams"></param>
        /// <param name="lpszDir"></param>
        /// <param name="FsShowCmd"></param>
        /// <returns></returns>
        [DllImport("shell32.dll", EntryPoint = "ShellExecute")]
        private static extern int OpenFolder(IntPtr hwnd, StringBuilder lpszOp, StringBuilder lpszFile, StringBuilder lpszParams, StringBuilder lpszDir, int FsShowCmd);
        //     OpenFolder(IntPtr.Zero, new StringBuilder("open"), new StringBuilder("explorer.exe"),new StringBuilder(path), new StringBuilder(string.Empty), 1);

        /// <summary>
        /// 用explorer找开文件夹
        /// </summary>
        /// <param name="strPath"></param>
        public static void OpenFoler(string strPath)
        {
            ShellExecute(0, "open", "explorer.exe", strPath, string.Empty, 1);
        }

        /// <summary>
        /// 用explorer打开文件filePath所在的目录并选中该文件
        /// </summary>
        /// <param name="filePath"></param>
        public static void OpenFolderAndSelectedFile(string filePath)
        {
            WinExec(@"explorer /n,/select," + filePath, 1);
        }

        /// <summary>
        ///  用PS打开出图片，如果picpath 为NULL则打开PS
        /// </summary>
        /// <param name="picPath"></param>
        /// <returns></returns>
        public static bool OpenPicByPs(string picPath)
        {
            if (ShellExecute(0, "open", "Photoshop.exe", null, picPath, 1) == 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 查看窗体是否找开，如果开了就返回TURE
        /// </summary>
        /// <param name="windName"></param>
        /// <returns></returns>
        public static bool WindowIsOpen(string windName)
        {
            if (((int)FindWindow(null, windName)) > 0)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 移动文件
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        /// <param name="flag">1如果文件存在，则替换；2如移动到不同的卷，则复制文件并删除原来的文件；3移动操作在系统重启后才真正执行</param>
        /// <returns></returns>
        [DllImport("kernel32", EntryPoint = "MoveFileExW", CharSet = CharSet.Unicode)]
        public static extern bool MoveFile(string src, string dst, long flag);

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        public static extern int DeleteFile(string src);

        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="lpExistingFileName"></param>
        /// <param name="lpNewFileName"></param>
        /// <param name="bFailIfExists"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool CopyFile([MarshalAs(UnmanagedType.LPStr)] string src, [MarshalAs(UnmanagedType.LPStr)] string dst, [MarshalAs(UnmanagedType.Bool)] bool bFailIfExists);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int CopyFileA(string lpExistingFileName, string lpNewFileName, int bFailIfExists);

        /// <summary>
        /// 先复制然后删除原来的文件夹，支持不同的卷
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        /// <returns></returns>
        public static bool CopyAndDelFile(string src, string dst)
        {
            if (!File.Exists(dst))
            {
                return MoveFile(src, dst, 2);
            }

            return true;
        }



        /// <summary>
        /// 移动目录,如果目标处没有此目录，则创建
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        /// <returns></returns>
        public static bool MoveDirectory(string src, string dst, out string errMsg)
        {
            errMsg = "";
            string FolderName = src.Substring(src.LastIndexOf("\\") + 1);
            dst += "\\" + FolderName;

            try
            {
                if (!Directory.Exists(dst))
                {
                    Directory.CreateDirectory(dst);
                }

                foreach (var fi in Directory.GetFiles(src))
                {
                    //MoveFile(fi, dst + "\\" + fi.Substring(fi.LastIndexOf("\\") + 1), 2);
                    //File.Copy(fi, dst + "\\" + fi.Substring(fi.LastIndexOf("\\") + 1), true);

                    FileInfo fiTemp = new FileInfo(fi);
                    //判断文件属性是否只读?是则修改为一般属性再删除
                    if (fiTemp.Attributes.ToString().IndexOf("ReadOnly") != -1)
                    {
                        fiTemp.Attributes = FileAttributes.Normal;
                    }


                    if (FileBLL.CopyFileA(fi, dst + "\\" + fi.Substring(fi.LastIndexOf("\\") + 1), 0) == 0)
                    {
                        errMsg = "在移动文件时出错\n" + fi;
                        return false;
                    }
                }
                foreach (var di in Directory.GetDirectories(src))
                {
                    if (!MoveDirectory(di, dst, out errMsg))//如果出错了就中断
                        return false;
                }

            }
            catch (Exception ex)
            {
                errMsg = "在移动文件时出错：\n" + ex.Message;
                return false;
            }
            return true;
        }


        //private char[] INVAILIDATION_STRING = new char[] { '\\', '/', ':', '*', '?', '\"', '<', '>', '|' };
        private const char REPLACE_CHAR = '_';

        /// <summary>
        /// 替换一些建文件夹时不应出现的字符统一替换成"_"
        /// </summary>
        /// <param name="oldPath"></param>
        /// <returns></returns>
        public static string GetValidateFolderName(string oldPath)
        {
            char[] INVAILIDATION_STRING = new char[] { '\\', '/', ':', '*', '?', '\"', '<', '>', '|' };
            for (int i = 0; i < INVAILIDATION_STRING.Length; i++)
            {
                if (oldPath.IndexOf(INVAILIDATION_STRING[i]) > -1)
                {
                    oldPath = oldPath.Replace(INVAILIDATION_STRING[i], REPLACE_CHAR);
                }
            }

            return oldPath;
        }
        /// <summary>
        /// 建立文件夹
        /// </summary>
        /// <param name="strPath"></param>
        /// <returns></returns>
        public static bool CreateDrictory(string strPath)
        {
            if (!string.IsNullOrEmpty(strPath))
            {
                if (!Directory.Exists(strPath))
                {
                    try
                    {
                        Directory.CreateDirectory(strPath);
                        return true;
                    }
                    catch (IOException ioex)
                    {
                        //指定的目录是只读的
                        return false;
                    }
                    catch (UnauthorizedAccessException uex)
                    {
                        return false;
                        //调用方法没有权限
                    }
                    catch (Exception)
                    {
                        return false;
                        //文件夹路径不合法
                    }

                }
                else
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 删除目录及其子目录
        /// </summary>
        /// <param name="dir"></param>
        public static void DeleteDirectory(string dir)
        {
 
            foreach (string var in Directory.GetDirectories(dir))
            {
                DeleteDirectory(var);
            }
            foreach (string var in Directory.GetFiles(dir))
            {
                //File.Delete(var);
                //如果有则删除
                FileInfo fi = new FileInfo(var);
                //判断文件属性是否只读?是则修改为一般属性再删除
                if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
                {
                    fi.Attributes = FileAttributes.Normal;
                }

                int result = DeleteFile(var);
            }
            //Directory.Delete(dir);
            if (Directory.GetDirectories(dir).Length == 0 && Directory.GetFiles(dir).Length == 0)
            {
                DirectoryInfo dinfo = new DirectoryInfo(dir);
                dinfo.Attributes = FileAttributes.Normal;  
                Directory.Delete(dir);
                return;
            }
        }

    }
}
